#ifndef __RED_EXCEPTION_OBJECT_H__
#define __RED_EXCEPTION_OBJECT_H__

#include "redobject.h"

typedef struct _RedExceptionObject
{
	RedObject_HEAD

	int				 ex_pos;
	int				 ex_line;
	RedObject		*ex_message;
	RedObject		*ex_callstack;
} RedExceptionObject;

/* Base class of exceptions */
RED_EXPORT extern RedTypeObject RedExc_Exception;

/* Special exceptions */
RED_EXPORT extern RedTypeObject RedExc_SystemExit;
RED_EXPORT extern RedTypeObject RedExc_KeyboardInterrupt;

/* Exception classes */
RED_EXPORT extern RedTypeObject RedExc_IOError;
RED_EXPORT extern RedTypeObject RedExc_OSError;
RED_EXPORT extern RedTypeObject RedExc_NameError;
RED_EXPORT extern RedTypeObject RedExc_TypeError;
RED_EXPORT extern RedTypeObject RedExc_IndexError;
RED_EXPORT extern RedTypeObject RedExc_ValueError;
RED_EXPORT extern RedTypeObject RedExc_FormatError;
RED_EXPORT extern RedTypeObject RedExc_ImportError;
RED_EXPORT extern RedTypeObject RedExc_MemoryError;
RED_EXPORT extern RedTypeObject RedExc_CompileError;
RED_EXPORT extern RedTypeObject RedExc_RuntimeError;
RED_EXPORT extern RedTypeObject RedExc_ArgumentError;
RED_EXPORT extern RedTypeObject RedExc_InternalError;
RED_EXPORT extern RedTypeObject RedExc_AttributeError;
RED_EXPORT extern RedTypeObject RedExc_FloatPointError;
RED_EXPORT extern RedTypeObject RedExc_UnhashableError;
RED_EXPORT extern RedTypeObject RedExc_NotCallableError;
RED_EXPORT extern RedTypeObject RedExc_NotPrintableError;
RED_EXPORT extern RedTypeObject RedExc_RecursionTooDepthError;

#define RedException_Message(o)			(((RedExceptionObject *)(o))->ex_message)
#define RedException_CallStack(o)		(((RedExceptionObject *)(o))->ex_callstack)

RED_EXPORT RedObject *RedException_Exception(void);

RED_EXPORT void RedException_Throw(RedTypeObject *exception);
RED_EXPORT void RedException_ThrowErrno(RedTypeObject *exception);
RED_EXPORT void RedException_ThrowObject(RedTypeObject *exception, RedObject *object);
RED_EXPORT void RedException_ThrowFormat(RedTypeObject *exception, const char *format, ...);

RED_EXPORT void RedException_Clear(void);
RED_EXPORT void RedException_Rewind(RedObject *frame);

#endif /* __RED_EXCEPTION_OBJECT_H__ */
